package com.nai365.nart.operation.listener;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.nai365.nart.blockchain.dto.TransferResultDto;
import com.nai365.nart.member.dto.RecoveryDto;
import com.nai365.nart.member.dto.SimpleMemberDto;
import com.nai365.nart.member.entity.WalletChange;
import com.nai365.nart.operation.config.RabbitmqConfig;
import com.nai365.nart.operation.entity.CompoundRecord;
import com.nai365.nart.operation.entity.CompoundRecordDetail;
import com.nai365.nart.operation.entity.RecoveryDetail;
import com.nai365.nart.operation.entity.RecoveryRecord;
import com.nai365.nart.operation.mapper.CompoundRecordDetailMapper;
import com.nai365.nart.operation.mapper.CompoundRecordMapper;
import com.nai365.nart.operation.mapper.RecoveryDetailMapper;
import com.nai365.nart.operation.mapper.RecoveryRecordMapper;
import com.nai365.nart.operation.service.MemberService;
import com.nai365.nart.operation.service.OrderService;
import com.nai365.nart.operation.service.ProductService;
import com.nai365.nart.order.entity.OrderItem;
import com.nai365.nart.product.entity.SkuInfo;
import com.rabbitmq.client.Channel;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

/**
 * DDC Listener
 *
 * @author linco
 * @date 2020-07-24
 * @since 1.0
 * @since 1.0
 */
@Component
@AllArgsConstructor
@Slf4j
public class DdcListener {

	private final RecoveryDetailMapper recoveryDetailMapper;

	private final RecoveryRecordMapper recoveryRecordMapper;

	private final CompoundRecordDetailMapper compoundRecordDetailMapper;

	private final CompoundRecordMapper compoundRecordMapper;

	private final ProductService productService;

	private final MemberService memberService;

	private final OrderService orderService;

	/**
	 * 回收处理
	 *
	 * @param transferResultDto
	 * @param message
	 * @param channel
	 * @throws IOException
	 */
	@RabbitListener(queues = {RabbitmqConfig.RECOVERY_QUEUE})
	@Transactional
	public void receiveRecovery(TransferResultDto transferResultDto, Message message, Channel channel) throws IOException {
		try {
			RecoveryDetail recoveryDetail = recoveryDetailMapper.selectById(transferResultDto.getRequestId());
			if (recoveryDetail != null) {
				SkuInfo skuInfo = productService.findSkuByIdInner(recoveryDetail.getSkuId());
				if (skuInfo != null) {
					recoveryDetail.setTxHash(transferResultDto.getTxHash());
					recoveryDetail.setStatus(1);
					recoveryDetailMapper.updateById(recoveryDetail);
					LambdaQueryWrapper<RecoveryDetail> queryWrapper = Wrappers.lambdaQuery();
					queryWrapper.eq(RecoveryDetail::getRecordId, recoveryDetail.getRecordId()).eq(RecoveryDetail::getStatus, 0);
					if (recoveryDetailMapper.selectCount(queryWrapper) == 0) {
						RecoveryRecord recoveryRecord = recoveryRecordMapper.selectById(recoveryDetail.getRecordId());
						recoveryRecord.setStatus(1);
						//转余额
						RecoveryDto recoveryDto = new RecoveryDto();
						recoveryDto.setUserId(recoveryRecord.getUserId());
						recoveryDto.setRecoveryRMB(recoveryRecord.getRecoveryAmount());
						recoveryDto.setFromUserId(1L);
						recoveryDto.setToUserId(recoveryRecord.getUserId());
						recoveryDto.setMark("藏品回收:" + recoveryRecord.getId());
						WalletChange walletChange = memberService.recoveryGoods(recoveryDto);
						recoveryRecord.setWalletSerial(walletChange.getId());
						recoveryRecord.updateById();
					}
					skuInfo.setOwnerAddress("0x49cb0e9a80887e89255e005fc7919b598f5b0851");
					skuInfo.setOwnerId(-1L);
					skuInfo.setTxHash(transferResultDto.getTxHash());
					skuInfo.setTxId(transferResultDto.getTxId());
					productService.updateSkuInner(skuInfo);
					channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
					return;
				}
			}
			channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);
		} catch (Exception e) {
			log.error("销毁DDC失败!", e);
			channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);
		}
	}

	/**
	 * 合成处理
	 *
	 * @param transferResultDto
	 * @param message
	 * @param channel
	 * @throws IOException
	 */
	@RabbitListener(queues = {RabbitmqConfig.COMPOUND_QUEUE})
	public void receiveCompound(TransferResultDto transferResultDto, Message message, Channel channel) throws IOException {
		try {
			log.info("transferResultDto:{}", transferResultDto);
			String[] split = transferResultDto.getRequestId().split("-");
			Long id = Long.valueOf(split[1]);
			String type = split[0];
			LambdaQueryWrapper<CompoundRecordDetail> queryWrapper = Wrappers.lambdaQuery();
			queryWrapper.eq(CompoundRecordDetail::getStatus, 0);
			CompoundRecord record;
			if (type.equals("detail")) {
				CompoundRecordDetail detail = compoundRecordDetailMapper.selectById(id);
				detail.setStatus(1);
				detail.setTxHash(transferResultDto.getTxHash());
				compoundRecordDetailMapper.updateById(detail);
				queryWrapper.eq(CompoundRecordDetail::getCompoundRecordId, detail.getCompoundRecordId());
				record = compoundRecordMapper.selectById(detail.getCompoundRecordId());
				SkuInfo skuInfo = productService.findSkuByIdInner(detail.getSkuId());
				skuInfo.setTxId(transferResultDto.getTxId());
				skuInfo.setTxHash(transferResultDto.getTxHash());
				skuInfo.setOwnerId(-1L);
				skuInfo.setOwnerAddress(transferResultDto.getTo());
				skuInfo.setOwnerCount(skuInfo.getOwnerCount() + 1);
				productService.updateSkuInner(skuInfo);
			} else {
				record = compoundRecordMapper.selectById(id);
				record.setTxHash(transferResultDto.getTxHash());
				record.setStatus(2);
				compoundRecordMapper.updateById(record);
				queryWrapper.eq(CompoundRecordDetail::getCompoundRecordId, id);
				SkuInfo skuInfo = productService.findSkuByIdInner(record.getTargetSkuId());
				skuInfo.setTxId(transferResultDto.getTxId());
				skuInfo.setTxHash(transferResultDto.getTxHash());
				skuInfo.setOwnerId(record.getUserId());
				skuInfo.setOwnerAddress(transferResultDto.getTo());
				skuInfo.setOwnerCount(skuInfo.getOwnerCount() + 1);
				skuInfo.setPublishStatus(0);
				productService.updateSkuInner(skuInfo);
			}
			if (compoundRecordDetailMapper.selectCount(queryWrapper) == 0 && record.getStatus().equals(2)) {
				record.setStatus(1);
				compoundRecordMapper.updateById(record);
			}
			channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
		} catch (Exception e) {
			log.error("合成失败!", e);
			channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);
		}
	}


}
